﻿// @l:距离左边的值，null代表自适应。
function XPosition(l, t, r, b, w, h) {
    this.l = l;
    this.t = t;
    this.r = r;
    this.b = b;
    this.w = w;
    this.h = h;
}
// 图形
function XShape(domEl) {
    this._domEl = domEl;
    this._pos = { x: 0, y: 0 };
    this._size = { w: 0, h: 0 };

    this._position = null;

    // 设置左上角坐标
    this.setPos = function (x, y) {
        this._pos.x = x;
        this._pos.y = y;
        this.onPosChanged();
    }

    // 设置大小
    this.setSize = function (w, h) {
        this._size.w = w;
        this._size.h = h;
        this.onSizeChanged();
    }

    // 获取图像相关的连接点
    this.getLinkPos = function () {

    }

    // 更新图形，根据所在容器的位置和大小来更新图形的位置和大小
    // @containerPos:Point容器的位置
    // @containerSize:Size容器的大小
    this.update = function (containerPos, containerSize) {
        var x, y, w, h;
        if (this._position.w == null) {
            // 宽度需要自动计算
            if (this._position.l != null) {
                if (this._position.r != null) {
                    w = containerSize.w - this._position.l - this._position.r;
                } else {
                    w = containerSize.w - this._position.l;
                }
            } else {
                if (this._position.r != null) {
                    w = containerSize.w - this._position.r;
                } else {
                    w = containerSize.w;
                }
            }
        } else {
            w = this._position.w;
        }

        if (this._position.h == null) {
            // 自动计算高度
            if (this._position.t != null) {
                if (this._position.b != null) {
                    h = containerSize.h - this._position.t - this._position.b;
                } else {
                    h = containerSize.h - this._position.t;
                }
            } else {
                if (this._position.b != null) {
                    h = containerSize.h - this._position.b;
                } else {
                    h = containerSize.h;
                }
            }
        } else {
            h = this._position.h;
        }

        if (this._position.l != null) {
            x = containerPos.x + this._position.l;
        } else {
            if (this.r != null) {
                x = containerPos.x - (containerSize.w - w - this._position.r);
            } else {
                x = containerPos.x + (containerSize.w - w) / 2;
            }
        }

        if (this._position.t != null) {
            y = containerPos.y + this._position.t;
        }
        else {
            if (this._position.b != null) {
                y = containerPos.y + (containerSize.h - h - this._position.b);
            } else {
                y = containerPos.y + (containerSize.h - h) / 2;
            }
        }

        this.setPos(x, y);
        this.setSize(w, h);
    }
}

//矩形
function XRectangle(domEl) {
    XShape.apply(this, [domEl]);

    this.onPosChanged = function () {
        this._domEl.style.left = this._pos.x + "px";
        this._domEl.style.top = this._pos.y + "px";
    }

    this.onSizeChanged = function () {
        this._domEl.style.width = this._size.w + "px";
        this._domEl.style.height = this._size.h + "px";
    }

    // 获取图像相关的连接点
    // 4个连接点
    //    0
    // 3     1
    //    2
    // @mode 0:in, 1:out, other:all
    this.getLinkPoints = function (mode) {
        if (mode == 0) {
            return [
                { dir: 'N', pos: { x: this._pos.x + this._size.w / 2, y: this._pos.y } }
            ];
        }
        else if (mode == 1) {
            return [
                { dir: 'E', pos: { x: this._pos.x + this._size.w, y: this._pos.y + this._size.h / 2 } },
                { dir: 'S', pos: { x: this._pos.x + this._size.w / 2, y: this._pos.y + this._size.h } },
                { dir: 'W', pos: { x: this._pos.x, y: this._pos.y + this._size.h / 2 } }
            ];
        }
        else {
            return [
                { dir: 'N', pos: { x: this._pos.x + this._size.w / 2, y: this._pos.y } },
                { dir: 'E', pos: { x: this._pos.x + this._size.w, y: this._pos.y + this._size.h / 2 } },
                { dir: 'S', pos: { x: this._pos.x + this._size.w / 2, y: this._pos.y + this._size.h } },
                { dir: 'W', pos: { x: this._pos.x, y: this._pos.y + this._size.h / 2 } }
            ];
        }
    }

    // 根据目标点的位置选择一个最优的连接点
    // @targetPos:Point目标点的信息
    // @mode:连接模式0:in, 1:out, other:all
    // return:Point
    this.selectLinkPoint = function (targetPos, mode) {
        if (mode == 0) {
            return this.getLinkPoints()[0];
        } else if (mode == 1) {
            var center = { x: this._pos.x + this._size.w / 2, y: this._pos.y + this._size.h / 2 };

            // 定位象限
            var quadrant = 0;
            if (targetPos.x >= center.x) {
                if (targetPos.y >= center.y) {
                    quadrant = 1;
                } else {
                    quadrant = 2;
                }
            } else {
                if (targetPos.y >= center.y) {
                    quadrant = 4;
                } else {
                    quadrant = 3;
                }
            }

            var index = 0;
            // 获取斜率
            var k = (center.y - targetPos.y) / (center.x - targetPos.x);
            if (k <= -1 || k >= 1) {
                if (quadrant == 1 || quadrant == 4) {
                    index = 2;
                } else {
                    if (quadrant == 3 || quadrant == 4) {
                        index = 3;
                    } else {
                        index = 1;
                    }
                }
            } else {
                if (quadrant == 3 || quadrant == 4) {
                    index = 3;
                } else {
                    index = 1;
                }
            }
            return this.getLinkPoints()[index];
        } else {
            var center = { x: this._pos.x + this._size.w / 2, y: this._pos.y + this._size.h / 2 };

            // 定位象限
            var quadrant = 0;
            if (targetPos.x >= center.x) {
                if (targetPos.y >= center.y) {
                    quadrant = 1;
                } else {
                    quadrant = 2;
                }
            } else {
                if (targetPos.y >= center.y) {
                    quadrant = 4;
                } else {
                    quadrant = 3;
                }
            }

            var index = 0;
            // 获取斜率
            var k = (center.y - targetPos.y) / (center.x - targetPos.x);
            if (k <= -1 || k >= 1) {
                if (quadrant == 2 || quadrant == 3) {
                    index = 0;
                } else {
                    index = 2;
                }
            } else {
                if (quadrant == 1 || quadrant == 2) {
                    index = 1;
                } else {
                    index = 3;
                }
            }
            return this.getLinkPoints()[index];
        }
    }
}

//圆形
function XCircle(domEl) {
    XShape.apply(this, [domEl]);

    this.onPosChanged = function () {
        this._domEl.style.left = this._pos.x + "px";
        this._domEl.style.top = this._pos.y + "px";
    }

    this.onSizeChanged = function () {
        this._domEl.style.width = this._size.w + "px";
        this._domEl.style.height = this._size.h + "px";
    }
}

//图片
function XImage(domEl) {
    XShape.apply(this, [domEl]);

    this.onPosChanged = function () {
        this._domEl.style.left = this._pos.x + "px";
        this._domEl.style.top = this._pos.y + "px";
    }

    this.onSizeChanged = function () {
        this._domEl.style.width = this._size.w + "px";
        this._domEl.style.height = this._size.h + "px";
    }

    this.setUrl = function (src) {
        this._domEl.src = src;
    }
}

//文本
function XText(domEl) {
    XShape.apply(this, [domEl]);

    this._domEl.setAttribute("font-size", "9px");

    this.onPosChanged = function () {
        this._domEl.style.left = this._pos.x + "px";
        this._domEl.style.top = this._pos.y + "px";
    }

    this.onSizeChanged = function () {
        this._domEl.style.width = this._size.w + "px";
        this._domEl.style.height = this._size.h + "px";
    }

    this.setText = function (text) {
        //innerHTML/innerText
        this._domEl.innerText = text;
    }
}

//线条
function XLine(domEl) {
    this._domEl = domEl;

    // 设置连线的坐标点信息
    // @value:Point[]
    this.setPoints = function (value) {
        var pointString = '';
        for (var index = 0; index < value.length; index++) {
            pointString += value[index].x + ',' + value[index].y + ' ';
        }
        this._domEl.points = pointString;
    }
}

//菱形
function XDiamond(domEl) {
    XShape.apply(this, [domEl]);

    this.onPosChanged = function () {
        this._domEl.style.left = this._pos.x + "px";
        this._domEl.style.top = this._pos.y + "px";
    }

    this.onSizeChanged = function () {
        this._domEl.style.width = this._size.w + "px";
        this._domEl.style.height = this._size.h + "px";
    }
}

// vml图形创建接口
function XGraphics() {
    //初始化VML的一些信息
    this.createCanvas = function () {
        //vml不需要容器,里面的节点都是dom,能直接被解析,设置一些命名空间和style
        var browser = navigator.appName;
        var b_version = navigator.appVersion
        var version = b_version.split(";");
        var trim_Version = version[1].replace(/[ ]/g, "");
        if (browser == "Microsoft Internet Explorer") {
            if (trim_Version == "MSIE6.0" || trim_Version == "MSIE7.0" || trim_Version == "MSIE8.0") {
                document.createStyleSheet().addRule(".vml", "behavior:url(#default#VML);display:inline-block;");
                document.namespaces.add('v', 'urn:schemas-microsoft-com:vml');
            }
        }

        //创建菱形的基本元素---shape的type指向#VML_Diamond
        var shapetype = document.createElement("<v:shapetype class='vml' id='VML_Diamond' coordsize='21600,21600' o:spt='4' path='m10800,l,10800,10800,21600,21600,10800xe'>");
        var stroke = document.createElement("v:stroke class='vml' joinstyle='miter' />");
        var path = document.createElement("<v:path class='vml' gradientshapeok='t' o:connecttype='rect' textboxrect='5400,5400,16200,16200'/>");
        shapetype.appendChild(stroke);
        shapetype.appendChild(path);
        document.body.appendChild(shapetype);

        var div = document.createElement("<div></div>");

        return div;
    }

    //菱形
    this.createDiamond = function () {
        var diamond = document.createElement("<v:shape class='vml' type='#VML_Diamond' style='position: absolute; />");
        return new XDiamond(diamond);
    }

    //矩形
    this.createRectangle = function () {
        var rect = document.createElement("<v:roundrect class='vml' style='position: absolute'></v:roundrect>");
        var shadow = document.createElement("<v:shadow class='vml' on='F' type='single' color='#b3b3b3' offset='5px,5px'/>");
        rect.appendChild(shadow);

        return new XRectangle(rect);
    }

    //圆形
    this.createCircle = function () {
        var oval = document.createElement("<v:oval class='vml' style='position: absolute'></v:oval>");
        return oval;
    }

    //线条
    this.createLine = function () {
        var line = document.createElement("<v:polyline filled='false'  class='vml' style='position: absolute' points=''></v:polyline>");
        var stroke = document.createElement("<v:stroke class='vml' EndArrow='Classic'></v:stroke>");
        line.appendChild(stroke);

        return new XLine(line);
    }

    //创建图片
    this.createImage = function () {
        var img = document.createElement("<v:image class='vml' style='position:absolute;' />");
        return new XImage(img);
    }

    //创建文本
    this.createText = function (textVal) {
        var text = document.createElement("<v:TextBox class='vml' style='font-size:9px; position:absolute;'>" + textVal + "</v:TextBox>");
        //var oText = new XText(text);
        //oText.setText(textVal);
        return new XText(text);
    }
}